package org.sam.swing;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;

import javax.swing.JComboBox;

/**
 * 扩展的swing JComboBox下拉列表框 +可以绑定代码操作
 * 
 * @author sam
 *
 * @param <E>
 */
public class JSComboBox<V, T> extends JComboBox<T> {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6360305558680319285L;

	/**
	 * 绑定的数据列表
	 */
	protected Vector<V> values;

	/**
	 * 无数据的下拉列表框
	 */
	public JSComboBox() {
		this(new Vector<V>(), new Vector<T>());
	}

	/**
	 * 实现绑定值和显示值2个操作 请按照次序绑定上
	 * 
	 * @param items
	 *            显示值
	 * @param datas
	 *            绑定值
	 */
	public JSComboBox(V[] datas, T[] items) {
		super(items);
		values = new Vector<V>(datas.length);
		int i, c;
		for (i = 0, c = items.length; i < c; i++)
			values.addElement(datas[i]);
	}

	/**
	 * 实现绑定值和显示值2个操作 请按照次序绑定上
	 * 
	 * @param items
	 *            显示值
	 * @param datas
	 *            绑定值
	 */
	public JSComboBox(Vector<V> datas, Vector<T> items) {
		super(items);
		this.values = datas;
	}

	/**
	 * 使用map对象绑定值的操作
	 * 
	 * @param datas
	 */
	public JSComboBox(Map<V, T> datas) {
		values = new Vector<V>(datas.size());
		for (Entry<V, T> entry : datas.entrySet()) {
			values.addElement(entry.getKey());
			super.addItem(entry.getValue());
		}
	}

	/**
	 * 获取当前选中的节点对应的值
	 * 
	 * @return 没有返回空
	 */
	public V getSelectedValue() {
		int index = this.getSelectedIndex();

		if (index < 0)
			return null;

		if (this.values == null || this.values.size() <= 0 || index >= this.values.size())
			return null;

		return values.get(this.getSelectedIndex());
	}

	/**
	 * 获取值
	 * 
	 * @param index
	 * @return
	 */
	public V getValueAt(int index) {
		if (index < 0)
			return null;

		if (this.values == null || this.values.size() <= 0 || index >= this.values.size())
			return null;

		return values.get(index);
	}
	
	/**
	 * 拿到值的集合副本
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Vector<V> getValues() {
		return (Vector<V>) values.clone();
	}

	/**
	 * 设置选择值
	 * 
	 * @param v
	 *            要选择的值
	 */
	public void setSelectedValue(V v) {
		int index = this.values.indexOf(v);
		this.setSelectedIndex(index);
	}
	
	/**
	 * 返回选中的绑定值
	 * @return
	 */
	public V getValue(){
		return this.getSelectedValue();
	}
	
	/**
	 * 设置选中值
	 * @param v
	 */
	public void setValue(V v){
		this.setSelectedValue(v);
	}

	/**
	 * 新写的增加一个数据行的方法
	 * @param value 绑定值
	 * @param item 显示内容
	 */
	public void addItem(V value,T item) {
		super.addItem(item);
		this.values.addElement(value);
	}
	
	/**
	 * 直接便利并添加
	 * @param datas
	 */
	public void addAll(Map<V, T> datas){
		if (datas == null || datas.isEmpty())
			return;
		
		for (Entry<V,T> item : datas.entrySet()){
			super.addItem(item.getValue());
			this.values.addElement(item.getKey());
		}
	}
	
	/**
	 * {@inheritDoc}
	 * 值设置为null
	 */
	@Override
	public void addItem(T item) {
		super.addItem(item);
		this.values.addElement(null);
	}

	/**
	 * 插入数据
	 */
	@Override
	public void insertItemAt(T item, int index) {
		super.insertItemAt(item, index);
		this.values.insertElementAt(null, index);
	}
	
	/**
	 * 插入数据
	 * @param value 绑定值
	 * @param item 显示值
	 * @param index 索引
	 */
	public void insertItemAt(V value,T item, int index) {
		super.insertItemAt(item, index);
		this.values.insertElementAt(value, index);
	}

	/**
	 * 删除数据
	 */
	@Override
	public void removeItem(Object anObject) {
		for(int i = 0 ; i < this.getModel().getSize(); i++){
			T t = this.getModel().getElementAt(i);
			if (t.equals(anObject)){
				this.values.remove(i);
				break;
			}
		}
		super.removeItem(anObject);
	}

	/**
	 * {@inheritDoc}
	 * 在某个位置删除
	 */
	@Override
	public void removeItemAt(int anIndex) {
		super.removeItemAt(anIndex);
		this.values.remove(anIndex);
	}

	/**
	 * 清空所有数据
	 */
	@Override
	public void removeAllItems() {
		super.removeAllItems();
		this.values.clear();
	}
	
}
